<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body,
        div,
        h2 {
            margin: 0;
            padding: 0;
        }

        body {
            background: url(image/bg.jpg);
            font: 12px/1.5 \5fae\8f6f\96c5\9ed1;
            color: #333;
        }

        #drag {
            position: absolute;
            top: 100px;
            left: 100px;
            width: 300px;
            height: 160px;
            background-color: #e9e9e9;
            border: 1px solid #444;
            border-radius: 5px;
            box-shadow: 0 1px 3px 2px #0ff;
        }

        #drag .title {
            position: relative;
            height: 27px;
            margin: 5px;
        }

        #drag .title h2 {
            font-size: 14px;
            height: 27px;
            line-height: 27px;
            border-bottom: 1px solid #0ff;
        }

        #drag .title div {
            position: absolute;
            height: 19px;
            top: 2px;
            right: 0;
        }

        #drag .title a,
        a.open {
            float: left;
            width: 21px;
            height: 19px;
            display: block;
            margin-left: 5px;
            background: url(image/tool.png) no-repeat;
        }

        a.open {
            position: absolute;
            top: 10px;
            left: 50%;
            margin-left: -10px;
            background-position: 0 0;
        }

        a.open:hover {
            background-position: 0 -29px;
        }

        #drag .title a.min {
            background-position: -29px 0;
        }

        #drag .title a.min:hover {
            background-position: -29px -29px;
        }

        #drag .title a.max {
            background-position: -60px 0;
        }

        #drag .title a.max:hover {
            background-position: -60px -29px;
        }

        #drag .title a.revert {
            background-position: -149px 0;
            display: none;
        }

        #drag .title a.revert:hover {
            background-position: -149px -29px;
        }

        #drag .title a.close {
            background-position: -89px 0;
        }

        #drag .title a.close:hover {
            background-position: -89px -29px;
        }

        #drag .content {
            overflow: auto;
            margin: 0 5px;
        }

        #drag .resizeBR {
            position: absolute;
            width: 14px;
            height: 14px;
            right: 0;
            bottom: 0;

            overflow: hidden;
            cursor: nw-resize;
            background: url(image/resize.png)
        }

        #drag .resizeL,
        #drag .resizeT,
        #drag .resizeR,
        #drag .resizeB,
        #drag .resizeLT,
        #drag .resizeTR,
        #drag .resizeLB {
            position: absolute;
            background: #000;
            overflow: hidden;
            opacity: 0;
        }

        #drag .resizeL,
        #drag .resizeR {
            top: 0;
            width: 5px;
            height: 100%;
            cursor: w-resize;
        }

        #drag .resizeR {
            right: 0;
        }

        #drag .resizeT,
        #drag .resizeB {
            width: 100%;
            height: 5px;
            cursor: n-resize;
        }

        #drag .resizeT {
            top: 0;
        }

        #drag .resizeB {
            bottom: 0;
        }

        #drag .resizeLT,
        #drag .resizeTR,
        #drag .resizeLB {
            width: 8px;
            height: 8px;
            background: #0ff;
        }

        #drag .resizeLT {
            top: 0;
            left: 0;
            cursor: nw-resize;
        }

        #drag .resizeTR {
            top: 0;
            right: 0;
            cursor: ne-resize;
        }

        #drag .resizeLB {
            left: 0;
            bottom: 0;
            cursor: ne-resize;
        }
    </style>
</head>

<body>
    <div id="drag">
        <div class="title">
            <h2>这是一个可以拖动的窗口</h2>
            <div>
                <a href="javascript:;" class="min" title="最小化"></a>
                <a href="javascript:;" class="max" title="最大化"></a>
                <a href="javascript:;" class="revert" title="还原"></a>
                <a href="javascript:;" class="close" title="关闭"></a>
            </div>
        </div>
        <div class="resizeL"></div>
        <div class="resizeT"></div>
        <div class="resizeR"></div>
        <div class="resizeB"></div>
        <div class="resizeLT"></div>
        <div class="resizeTR"></div>
        <div class="resizeBR"></div>
        <div class="resizeLB"></div>
        <div class="content">
            ① 窗口可以拖动；<br />
            ② 窗口可以通过八个方向改变大小；<br />
            ③ 窗口可以最小化、最大化、还原、关闭；<br />
            ④ 限制窗口最小宽度/高度。
        </div>

    </div>
</body>
<script>
    /*
     * 获取id， class， tagname
     */
    var get = {
        byId: function (id) {
            return typeof id === "string" ? document.getElementById(id) : null;
        },
        byClass: function (sClass, oParent) {
            // 带有类的标签，一般是数组类型，故需要一个数组来存储这些类
            var aClass = [];
            // 类名的匹配规则
            var reClass = new RegExp("(^|\s)" + sClass + "(\s|$)");
            // this指对象get本身
            var aElem = this.byTagName("*", oParent);
            for (var i = 0; i < aElem.length; i++) {
                reClass.test(aElem[i].className) && aClass.push(aElem[i]);
            }
            return aClass;
        },
        byTagName: function (elem, obj) {
            return (obj || document).getElementsByTagName(elem);
        }
    };

    var dragMinWidth = 250;
    var dragMinHeight = 124;

    /*
     * 拖曳函数
     */
    function drag(oDrag, handle) {
        var disX = 0,
            dixY = 0;
        var oMin = get.byClass("min", oDrag)[0];
        var oMax = get.byClass("max", oDrag)[0];
        var oRevert = get.byClass("revert", oDrag)[0];
        var oClose = get.byClass("close", oDrag)[0];
        handle = handle || oDrag;
        handle.style.cursor = "move";

        handle.onmousedown = function (event) {
            var event = event || window.event;
            disX = event.clientX - oDrag.offsetLeft;
            disY = event.clientY - oDrag.offsetTop;

            document.onmousemove = function (event) {
                var event = event || window.event;
                var iL = event.clientX - disX;
                var iT = event.clientY - disY;
                var maxL = document.documentElement.clientWidth - oDrag.offsetWidth;
                var maxT = document.documentElement.clientHeight - oDrag.offsetHeight;

                iL <= 0 && (iL = 0);
                iT <= 0 && (iT = 0);
                iL >= maxL && (iL = maxL);
                iT >= maxT && (iT = maxT);

                oDrag.style.left = iL + "px";
                oDrag.style.top = iT + "px";
                return false;
            };

            document.onmouseup = function (event) {
                document.onmouseup = null;
                document.onmousemove = null;
                this.releaseCapture && this.releaseCapture();
            };
            this.setCapture && this.setCapture();
            return false;
        };

        // 最大化按钮
        oMax.onclick = function () {
            oDrag.style.top = oDrag.style.left = 0;
            oDrag.style.width = document.documentElement.clientWidth - 2 + "px";
            oDrag.style.height = document.documentElement.clientHeight - 2 + "px";
            // 点击之后，最大按钮消失，还原按钮出现
            this.style.display = "none";
            oRevert.style.display = "block";
        }

        // 还原按钮
        oRevert.onclick = function () {
            oDrag.style.width = dragMinWidth + "px";
            oDrag.style.height = dragMinHeight + "px";

            oDrag.style.left = (document.documentElement.clientWidth - oDrag.offsetWidth) / 2 + "px";
            oDrag.style.top = (document.documentElement.clientHeight - oDrag.offsetHeight) / 2 + "px";

            this.style.display = "none";
            oMax.style.display = "block";
        };

        // 最小化按钮和关闭按钮
        oMin.onclick = oClose.onclick = function () {
            oDrag.style.display = "none";
            // 创建一个恢复窗口的图标
            var oA = document.createElement("a");
            oA.className = "open";
            oA.href = "javascript:;";
            oA.title = "还原";

            document.body.appendChild(oA);

            oA.onclick = function () {
                oDrag.style.display = "block";
                document.body.removeChild(this);
                this.onclick = null;
            };
        };

        // 阻止冒泡
        // 如果不阻止，在使用最小化等按钮的功能同时，还可以移动窗口
        oMin.onmousedown = oMax.onmousedown = oClose.onmousedown = function (event) {
            this.onfocus = function () {
                this.blur()
            }; //??????????????
            (event || window.event).cancelBubble = true;
        };
    }

    /*
     * 窗口大小改变
     */
    function resize(oParent, handle, isLeft, isTop, lockX, lockY) {
        handle.onmousedown = function (event) {
            var event = event || window.event;
            // 初始oDrag左侧或者上边偏移距离+鼠标相对触点所在小盒子的相对距离
            var disX = event.clientX - handle.offsetLeft;
            var disY = event.clientY - handle.offsetTop;
            // 获取oDrag的初始宽度、高度、左偏移量以及上偏移量
            var iParentTop = oParent.offsetTop;
            var iParentLeft = oParent.offsetLeft;
            var iParentWidth = oParent.offsetWidth;
            var iParentHeight = oParent.offsetHeight;

            document.onmousemove = function (event) {
                var event = event || window.event;
                // 计算移动前的初始值；
                // 当向左或者向上时，iL和iT或小于0
                var iL = event.clientX - disX;
                var iT = event.clientY - disY;

                // 设置
                var maxW = document.documentElement.clientWidth - iParentLeft - 2;
                var maxH = document.documentElement.clientHeight - oParent.offsetTop - 2;

                // 第一条件： 也一并获取到oDrag的实际参数
                var iW = isLeft ? iParentWidth - iL : handle.offsetWidth + iL;
                var iH = isTop ? iParentHeight - iT : handle.offsetHeight + iT;
                // 第二条件：控制移动方向
                isLeft && (oParent.style.left = iParentLeft + iL + "px");

                isTop && (oParent.style.top = iParentTop + iT + "px");

                console.log(iParentLeft);


                // 第三条件： 设置最小和最大范围
                // 这里有个问题：最大的范围并不仅仅是浏览器可视窗口的大小
                // 还有两个界限需要限定：左侧偏移最大距离和右侧偏移最大距离
                // oDrag.offsetLeft <= iParentLeft & oDrag.offsetLeft >=0
                // document.documentElement.clientHeight - oDrag.offsetLeft - oDrag.offsetWidth <= iParentLeft & document.documentElement.clientHeight - oDrag.offsetLeft - oDrag.offsetWidth >= 0
                iW <= dragMinWidth && (iW = dragMinWidth); //设置最小值

                iW >= maxW && (iW = maxW); //设置最大值为浏览器
                // 输出最终值
                lockX || (oParent.style.width = iW + "px");

                iH <= dragMinHeight && (iH = dragMinHeight);
                iH >= maxH && (iH = maxH);
                lockY || (oParent.style.height = iH + "px");

                if ((isLeft && iW == dragMinWidth) || (isTop && iT == dragMinHeight)) {
                    document.onmousemove = null;
                }
                return false;
            };

            document.onmouseup = function (event) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
            return false;
        };
    }

    window.onload = window.onresize = function () {
        var oDrag = get.byId("drag");
        var oTitle = get.byClass("title", oDrag)[0];

        var oL = get.byClass("resizeL", oDrag)[0];
        var oT = get.byClass("resizeT", oDrag)[0];
        var oR = get.byClass("resizeR", oDrag)[0];
        var oB = get.byClass("resizeB", oDrag)[0];

        var oLT = get.byClass("resizeLT", oDrag)[0];
        var oTR = get.byClass("resizeTR", oDrag)[0];
        var oBR = get.byClass("resizeBR", oDrag)[0];
        var oLB = get.byClass("resizeLB", oDrag)[0];

        // 调用拖曳
        drag(oDrag, oTitle);

        // 四边
        resize(oDrag, oL, true, false, false, true);
        resize(oDrag, oT, false, true, true, false);
        resize(oDrag, oR, false, false, false, true);
        resize(oDrag, oB, false, false, true, false);

        // 四角
        resize(oDrag, oLT, true, true, false, false);
        resize(oDrag, oTR, false, true, false, false);
        resize(oDrag, oBR, false, false, false, false);
        resize(oDrag, oLB, false, false, true, false);
        oDrag.style.left = (document.documentElement.clientWidth - oDrag.offsetWidth) / 2 + "px";
        oDrag.style.top = (document.documentElement.clientHeight - oDrag.offsetHeight) / 2 + "px";
    }
</script>

</html>